using System;
using FamilyTreeProject.Framework.Entities;
using FamilyTreeProject.Framework.Enums;
using FamilyTreeProject.Framework.Structures;
using FamilyTreeProject.Data.Repositories;
using FamilyTreeProject.ComponentModel;
using FamilyTreeProject.Framework.Collections;

namespace FamilyTreeProject.Framework.Proxies
{
    /// <summary>
    /// The IndividualProxy Class provides a Proxy to the Individual class
    /// </summary>
    public class IndividualProxy : EntityProxyBase<IIndividual>, IIndividual
    {

        #region Private Members

        private IIndividual individual = null;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates an IndividualProxy object from its Id
        /// </summary>
        /// <remarks>The collections created use the default "Repositories"</remarks>
        /// <param name="individualID">The id of the Individual</param>
        protected internal IndividualProxy(int individualID) : base(individualID)  { }

        /// <summary>
        /// Creates an IndividualProxy object from its Id
        /// </summary>
        /// <param name="individualID">The id of the Individual</param>
        /// <param name="repository">The IFamilyTreeRepository to use.</param>
        protected internal IndividualProxy(int individualID, IFamilyTreeRepository repository) : base(individualID, repository) { }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Gets the Individual from the Data Store
        /// </summary>
        /// <returns>The Individual</returns>
        protected override IIndividual GetObject()
        {
            if (individual == null)
            {
                individual = Repository.IndividualRepository.GetIndividual(Id);
            }
            return individual;
        }

        #endregion


        #region IIndividual Members

        #region Public Properties

        /// <summary>
        /// Gets a Collection of Children of the Individual
        /// </summary>
        public IObjectCollection<IIndividual> Children
        {
            get { return GetObject().Children; }
        }

        /// <summary>
        /// Gets or sets the Death Status of the Individual
        /// </summary>
        public DeathStatus DeathStatus
        {
            get { return GetObject().DeathStatus; }
            set { GetObject().DeathStatus = value; }
        }

        /// <summary>
        /// Gets the Display Name of the Individual
        /// </summary>
        public string DisplayName
        {
            get { return GetObject().DisplayName; }
        }

        /// <summary>
        /// Gets a Collection of Events for the Individual
        /// </summary>
        public IObjectCollection<IEvent> Events
        {
            get { return GetObject().Events; }
        }

        /// <summary>
        /// Gets or sets the Father of the Individual
        /// </summary>
        public IIndividual Father
        {
            get { return GetObject().Father; }
            set { GetObject().Father = value; }
        }

        /// <summary>
        /// Gets or sets the Mother of the Individual
        /// </summary>
        public IIndividual Mother
        {
            get { return GetObject().Mother; }
            set { GetObject().Mother = value; }
        }

        /// <summary>
        /// Gets or sets the Name of the Individual
        /// </summary>
        public Name Name
        {
            get { return GetObject().Name; }
            set { GetObject().Name = value; }
        }

        /// <summary>
        /// Gets a Collection of PersonalInfo objects for the Individual
        /// </summary>
        public IObjectCollection<IPersonalInfo> PersonalInfo
        {
            get { return GetObject().PersonalInfo; }
        }

        /// <summary>
        /// Gets or sets the Sex of the Individual
        /// </summary>
        public Sex Sex
        {
            get { return GetObject().Sex; }
            set { GetObject().Sex = value; }
        }

        /// <summary>
        /// Gets a Colelction of Spouses for the Individual
        /// </summary>
        public IObjectCollection<IIndividual> Spouses
        {
            get { return GetObject().Spouses; }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Gets the Age of the Individual, at a specified date
        /// </summary>
        /// <param name="date">The date to use to calculate the Individuals Age</param>
        /// <returns>The Age of the Individual</returns>
        public int GetAge(Date date)
        {
            return GetObject().GetAge(date);
        }

        /// <summary>
        /// Gets the Birth Event for the Individual
        /// </summary>
        /// <returns>The Birth Event</returns>
        public IEvent GetBirthEvent()
        {
            return GetObject().GetBirthEvent();
        }

        /// <summary>
        /// Gets the Death Event for the Individual
        /// </summary>
        /// <returns>The Death Event</returns>
        public IEvent GetDeathEvent()
        {
            return GetObject().GetDeathEvent();
        }

        /// <summary>
        /// Gets a String representation of the Individual, using a specified format.
        /// </summary>
        /// <param name="format">The format to use.</param>
        /// <returns>A String</returns>
        public string ToString(NameFormat format)
        {
            return GetObject().ToString(format);
        }

        #endregion

        #endregion

        #region IComparable Members

        /// <summary>
        /// Compares the current instance of IndividualProxy to another instance.
        /// </summary>
        /// <param name="obj">The object to compare with</param>
        /// <returns>A value indicating which object is "larger"</returns>
        public int CompareTo(object obj)
        {
            return GetObject().CompareTo(obj);
        }

        #endregion

    }
}
